home *** CD-ROM | disk | FTP | other *** search
- /*
- Plasma by Jan Mller & Erik Hansen. (& rewrite by Karl Weller)
-
- It was compiled in Borland c++, in ANSI mode, using the HUGE memory model.
- Feel free to use it as you desire, you may even name it after your
- grandmother. We don't care.
- The reason why we made it? Well... First of all we wanted to make some
- plasma, just for fun. But when we had finished it turned out to be much
- faster than the plasma we have seen in intros, demos etc...
- Normally the color-cells are 2x4 4x4 or even larger, the 2x4 cell-plasma
- was awfully slow, bot ours ain't, even though it is 2x2 cells.
- Well how can that be??? ^^^^^^^^^
- Our secret lies in the plasma-calculation!
- (I assume you have guessed that part already)
- We simply calculate as much as possible before we start showing the goddies.
- The table 'Tab1' is a simple table (320x200 yields 64k) with the distance
- from (x,y) to the center (rounded off to char by simple overflow). The second
- table 'Tab2' is similar to 'Tab1', except we molested it with sine.
- In the mainloop we calculate a body (160x100) by accessing the two tables
- with different pairs of (x,y) and add them.
- (see for yourself in 'CalculateBody')
- And KaPoW. We have the fastest plasma...
- (i.e. the fastest we have ever seen.(on a 486)) If I am not correct then please notify me.
-
- If you have any questions, comments or whips, then we would be happy to answer.
-
- Contact us trough E-Mail:
-
- fwiffo@daimi.aau.dk
-
- or
-
- martino@daimi.aau.dk
-
- (If you can optimize it (e.g. write it in asm) we would be very interested
- to see the results!)
-
- Modified by: Karl Weller CI$ 74620,2112
- to work with all VGA screens and eliminate startup calculations!
-
- Final version uses VGA 320x256 x 4 pages (kind of like MODE-X)
-
- 02-04-94 (KAW) Final tweaking of program! finish vga page swapping & got
- palette cycling working again (faster)!
-
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <conio.h>
- #include <math.h>
- #include <fcntl.h>
- #include <io.h>
- #include <dos.h>
- #define uchar unsigned char
- #define ulong unsigned long
- #define uint unsigned int
- #define box_w 160
- #define box_h 100
- double pi=3.141592654;
- //-------------------------------------------------
- uchar far *body; // buffer for the bitmap body
- //char far *body = (char far *)0xa0000000;
- extern uchar tab1[]; // table one for thr plasma
- extern uchar tab2[]; // table two for the plasma
- extern unsigned char far pal[]; // palette
- unsigned char pal2[800];
-
- //-------------------------------------------------
-
- void SetMode(char mode)
- {
- _asm {
- mov ah,0x00
- mov al,mode
- int 0x10
- }
- }
- char GetMode(void )
- {
- char mode;
-
- _asm {
- mov ah,0x0f
- int 0x10
- mov mode,al
- }
- return (mode);
- }
-
- void waitvrt(void )
- {
- _asm {
- mov dx,0x3da ; wait for retrace
- bra1:
- in al,dx
- and al,8
- jnz bra1
- bra2:
- in al,dx
- and al,8
- jz bra2
- }
- }
-
- void setpal(void) {
- unsigned int sg,of;
- char far *p = (char far *)pal2;
-
- sg = FP_SEG(p);
- of = FP_OFF(p);
-
- _asm {
- push ds
- push es
- push si
- push di
- pushf
-
- cld
- mov cx,sg
- mov si,of
- mov dx,03C8h ;port address of DAC register
- mov bx,0 ;first register to update
- mov ax,bx
- cli
- out dx,al ;start with this DAC
-
- inc dx ;port address where RGB info is written
- mov ds,cx
- mov cx,256 ;number of DAC registers to update
- setdacloop:
- lodsb
- out dx,al
- lodsb
- out dx,al
- lodsb
- out dx,al
- loop setdacloop
- sti
-
- popf
- pop di
- pop si
- pop es
- pop ds
-
- }
- }
-
- static double r=1.0/6.0*3.141592654,g=3.0/6.0*3.141592654,b=5.0/6.0*3.141592654;
-
- int palcnt = 1;
- int pald = 1;
- void CalculateColors()
- {
- int i=0,j,k,l;
-
- #if 0
- double u,v;
- while(i<256)
- {
- u=2*pi/256*i;
- //#define mycol(u,a) (max(0.0,cos((u)+(a))))*63 // try this line instead
- #define mycol(u,a) (cos((u)+(a))+1)*31
- pal[i*3] = mycol(u,r);
- pal[i*3+1] = mycol(u,g);
- pal[i*3+2] = mycol(u,b);
- /*
- SetPal(i,mycol(u,r),mycol(u,g),mycol(u,b));
- */
- i++;
- }
- /*
- waitvrt();
- setpal();
- */
- r+=0.05;
- g-=0.05;
- b+=0.1;
- #else
- memcpy(pal2,pal+(palcnt*768),768);
- palcnt += pald;
- if (palcnt < 1) {
- pald = 1;
- palcnt = 2;
- }
- else if (palcnt >= 49) {
- pald = -1;
- palcnt = 48;
- }
- #endif
- }
-
- void CalculateBody(unsigned x1,unsigned y1,unsigned x2,unsigned y2,unsigned x3,unsigned y3,unsigned x4,unsigned y4,unsigned roll)
- {
- unsigned int i=0,j,x=0,t1,t2,t3,t4;
- uchar b,c;
-
- while(i<box_h) {
- j=0;
- t1 = 320*(i+y1)+x1;
- t2 = 320*(i+y2)+x2;
- t3 = 320*(i+y3)+x3;
- t4 = 320*(i+y4)+x4;
- while(j<box_w) { // this is the heart of the plasma
- b= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
- c= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
- body[x] = body[x+80] = body[x+16000] = body[x+16080] = b;
- body[x+32000] = body[x+48000] = body[x+32080] = body[x+48080] = c;
- j+=2;
- x++;
- }
- x+=80;
- i++;
- }
- }
-
-
- void outdisp(int page)
- {
- unsigned char far *addr = (unsigned char far*) (0xA0000000+(0x8000000*page) );
- unsigned int sg,of,ad;
- sg = FP_SEG(body);
- of = FP_OFF(body);
- ad = FP_SEG(addr);
-
- outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
- outp(0x3C5,1);
- _asm {
- push ds
- push es
- push si
- push di
-
- mov cx,sg
- mov dx,of
- mov ax,ad ; destination screen address.
- mov es,ax ; into ES
- xor ax,ax
- mov di,ax
- mov si,dx
- mov ds,cx
- mov cx,8000
-
- rep movsw ; move image to screen
- pop di
- pop si
- pop es
- pop ds
- }
-
- // memcpy(addr,body,16000);
- outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
- outp(0x3C5,2);
- _asm {
- push ds
- push es
- push si
- push di
-
- mov cx,sg
- mov dx,of
- add dx,16000
- mov ax,ad ; destination screen address.
- mov es,ax ; into ES
- xor ax,ax
- mov di,ax
- mov si,dx
- mov ds,cx
- mov cx,8000
-
- rep movsw ; move image to screen
- pop di
- pop si
- pop es
- pop ds
- }
- // memcpy(addr,body+(unsigned)16000,16000);
- outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
- outp(0x3C5,4);
- _asm {
- push ds
- push es
- push si
- push di
-
- mov cx,sg
- mov dx,of
- add dx,32000
- mov ax,ad ; destination screen address.
- mov es,ax ; into ES
- xor ax,ax
- mov di,ax
- mov si,dx
- mov ds,cx
- mov cx,8000
-
- rep movsw ; move image to screen
- pop di
- pop si
- pop es
- pop ds
- }
- // memcpy(addr,body+(unsigned)32000,16000);
- outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
- outp(0x3C5,8);
- _asm {
- push ds
- push es
- push si
- push di
-
- mov cx,sg
- mov dx,of
- add dx,48000
- mov ax,ad ; destination screen address.
- mov es,ax ; into ES
- xor ax,ax
- mov di,ax
- mov si,dx
- mov ds,cx
- mov cx,8000
-
- rep movsw ; move image to screen
-
- pop di
- pop si
- pop es
- pop ds
- }
- // memcpy(addr,body+(unsigned)48000,16000);
- }
-
- int _cdecl main(void)
- {
- double circle1=0,circle2=0,circle3=0,circle4=0,circle5=0,circle6=0,circle7=0,circle8=0;
- unsigned int x1,y1,x2,y2,x3,y3,x4,y4,roll=0,bh,bw;
- unsigned int fnd,j,i=0;
- int which=1;
- char oldmode;
-
- oldmode=GetMode();
-
- body = malloc((unsigned)65000);
- memset(body,0,(unsigned int)65000);
-
- SetMode(19);
- _asm {
- mov dx, 3CEh ; Tell the Graphics Controller
- mov al, 5 ; to change the graphics mode
- out dx, al ; (register 5) to use linear
- inc dx ; addresses instead of seperating
- in al, dx ; the odd and even addresses.
- and al, 11101111b ;
- out dx, al ;
- dec dx ;
-
- mov al, 6 ; Tell the Graphics Controller
- out dx, al ; to change the misc. register
- inc dx ; (register 6) to use linear
- in al, dx ; addresses instead of seperating
- and al, 11111101b ; the odd and even addresses.
- out dx, al ;
-
- mov dx, 3C4h ; Tell the Sequencer Controller
- mov al, 4 ; to change the memory mode
- out dx, al ; (register 4) to disable chain4
- inc dx ; mode, and allow linear
- in al, dx ; processing on a bitplane.
- and al, 11110111b ;
- or al, 4 ;
- out dx, al ;
-
- mov ax, 0A000h ; Clear the screen.
- mov es, ax ;
- xor di, di ;
- mov ax, di ;
- mov cx, 8000h ;
- rep stosw ;
-
- mov dx, 3D4h ; Tell the CRT Controller to
- mov al, 14h ; change the underline location
- out dx, al ; (register 14h) to turn off
- inc dx ; the double word mode.
- in al, dx ;
- and al, 10111111b ;
- out dx, al ;
- dec dx ;
-
- mov al, 17h ; Tell the CRT Controller to
- out dx, al ; change the mode control
- inc dx ; (register 17h) to switch
- in al, dx ; to byte mode.
- or al, 01000000b ;
- out dx, al ;
- }
-
- bh = box_h/2;
- bw = box_w/2;
- while(1)
- {
- CalculateColors();
- setpal();
- circle1+=0.01416666666666;
- circle2-=0.01666666666666;
- circle3+=0.050;
- circle4-=0.03333333333333;
- circle5+=0.06666666666666;
- circle6-=0.0250;
- circle7+=0.05833333333333;
- circle8-=0.00833333333333;
- x2=(bw)+(bw)*sin(circle1);
- y2=(bh)+(bh)*cos(circle2);
- x1=(bw)+(bw)*cos(circle3);
- y1=(bh)+(bh)*sin(circle4);
- x3=(bw)+(bw)*cos(circle5);
- y3=(bh)+(bh)*sin(circle6);
- x4=(bw)+(bw)*cos(circle7);
- y4=(bh)+(bh)*sin(circle8);
- CalculateBody(x1,y1,x2,y2,x3,y3,x4,y4,roll+=5);
- if (which++ % 2) {
- outdisp(1);
- _asm {
- mov dx,0x3da ; wait for retrace
- bra1:
- in al,dx
- and al,8
- jnz bra1
- bra2:
- in al,dx
- and al,8
- jz bra2
-
- mov dx,0x3d4
- mov ax,0x800c
- out dx,ax
- }
- // outpw(0x3D4, 0x800C); /* Flip to other page, */
- }
- else {
- outdisp(0);
- if (kbhit()) break;
- _asm {
- mov dx,0x3da ; wait for retrace
- bra1a:
- in al,dx
- and al,8
- jnz bra1a
- bra2a:
- in al,dx
- and al,8
- jz bra2a
-
- mov dx,0x3d4
- mov ax,0x0c
- out dx,ax
- }
- // outpw(0x3D4, 0x0C); /* Flip to other page, */
- }
- }
- while(kbhit()) getch();
- free(body);
- /************************************/
- /* A Clean ending is a nice ending! */
- /* (K.W.) */
- /************************************/
- memset(body,0,(unsigned)64000);
- for(i=0;i<256;++i) {
- if (kbhit()) break;
- fnd=0;
- for(j=0;j<771;++j) {
- if (pal2[j]>=2) {
- pal2[j]-=2;
- ++fnd;
- }
- }
- waitvrt();
- setpal(); /* fade the pal */
- if (!fnd) break;
- }
- memset(pal2,0,771);
- waitvrt();
- setpal(); /* blank the pal */
- waitvrt();
- outpw(0x3D4, 0x0C);
- outdisp(1); /* blank page 1 */
- outpw(0x3D4, 0x800C);
- outdisp(0); /* blank page 0 */
- outpw(0x3D4, 0x0C);
-
- SetMode(oldmode);
- waitvrt();
- return 0;
- }